grammar test;

stat	:	class_head constpool;

class_head	:	'class' objName 'extends' objName  'minor' 'version' ':' INT 'major' 'version' ':' INT  ;


objName	:	ID ('.' ID)*;


constpool:	'Constant' 'pool' ':' const_body+;
const_body:    'const' CONST_INDEX '=' const_type SEMI  ;

const_type
	:	consttype_method |consttype_string|consttype_class|consttype_field|consttype_asciz|consttype_nameandtype;
consttype_method 
	:	 'Method'   CONST_INDEX '.' CONST_INDEX;
consttype_string 
	:	 'String'  CONST_INDEX;	
consttype_class 
	:	 'class'  CONST_INDEX;	
consttype_field 
	:	 'Field'  CONST_INDEX '.' CONST_INDEX;	
consttype_asciz
	:	ASCIZ;	
consttype_nameandtype 
	:	 'NameAndType' CONST_INDEX ':' CONST_INDEX;		


ASCIZ	:	'Asciz' '\t' ~('\n'|'\r'|';')*  ;

	
CONST_INDEX
	:   '#'('0'..'9')+;

ID  :	('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

INT :	'0'..'9'+
    ;

FLOAT
    :   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT
    ;

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

CHAR:  '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
    ;

fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;
    
    COLON
    :   ':'
    ;

SEMI
    :   ';'
    ;

